/*
 * USARTCommunications.c
 *
 * Created: 4/24/2012 3:47:23 PM
 *  Author: PAXS
 */ 
	#include "USARTCommunications.h"
/******************************************************************************
*							LOCAL MACRO DEFINITIONS
******************************************************************************/
	
	
/******************************************************************************
*   Local Type Definitions
******************************************************************************/
	enum{
		FILL_TXSTATE=0,
		SEND_TXSTATE,
		FINISH_TXSTATE,
		WAIT_TXSTATE
	};
	
	enum{
		WAIT_RXSTATE=0,
		RECEIVE_RXSTATE,
		FINISH_RXSTATE
	};
	USARTSM UsartTXCommSM,UsartRXCommSM;
	
/******************************************************************************
*   Global Variable Definitions
******************************************************************************/
	unsigned char USARTTXDataBuffer[UART_DATA_LENGTH],USARTRXDataBuffer[UART_DATA_LENGTH];
	volatile unsigned char  UsartTXCounter,UsartRXCounter;
	
/******************************************************************************
*   Local Variables Declarations
******************************************************************************/
	volatile unsigned char USARTTXBuffer[UART_PACKAGE_LENGTH],USARTRXBuffer[UART_PACKAGE_LENGTH];
	volatile unsigned char  UsartRXPackageEngage,UsartRXPackageEngageFlag;
	unsigned char  TXFlag;
	
/******************************************************************************
*   Local Function Prototypes
******************************************************************************/
	void (*const USARTTXCommunicationSM[]) (void);
	void (*const USARTRXCommunicationSM[]) (void);

/******************************************************************************
*   Static Variable Definitions
******************************************************************************/

/******************************************************************************
*   Global and Static Function Definitions
******************************************************************************/
/*****************************************************************************
 * Function: 	VfnUSARTTxCommunicationInit
 * Description: Init. States to run the Tx Communication State MAchine.
 * Parameters:	N/A
 * Caveats:		Non
 * Return:		N/A
 *****************************************************************************/	
	void VfnUSARTTxCommunicationInit(void)
	{
		UsartTXCommSM.ActualState = FILL_TXSTATE;
		UsartTXCounter = 0;
		TXFlag = 0;
	}
	
/*****************************************************************************
 * Function: 	VfnUSARTRxCommunicationInit
 * Description: Init. States to run the Rx Communication State MAchine.
 * Parameters:	N/A
 * Caveats:		Non
 * Return:		N/A
 *****************************************************************************/	
	void VfnUSARTRxCommunicationInit(void)
	{
		//#if USART_RX_INT == ON
		//UsartRXCommSM.ActualState = WAIT_RXSTATE;
		//UsartRXCounter = 0;
		//RXFlag = 0;
		//#endif
		//#if USART_RX_INT == OFF 
		UsartRXCommSM.ActualState = RECEIVE_RXSTATE;
		UsartRXCounter = 0;
		//RXFlag = 0;
		//#endif
	}
	
/*****************************************************************************
 * Function: 	VfnUSARTTxCommunication
 * Description: Run the USARTTXCommunicationSM. 
 * Parameters:	N/A
 * Caveats:		Non
 * Return:		1 - Transmission completed, 0 - busy
 *****************************************************************************/	
	unsigned char VfnUSARTTxCommunication (void)
	{
		USARTTXCommunicationSM[UsartTXCommSM.ActualState]();
		if(UsartTXCommSM.ActualState == FINISH_TXSTATE)
		{
			return 1;
		}
		else
		{
			return 0;
		}
	}
	
/*****************************************************************************
 * Function: 	VfnUSARTRxCommunication
 * Description: Run the USARTRXCommunicationSM.
 * Parameters:	N/A
 * Caveats:		Non
 * Return:		1 - Reception completed, 0 - busy
 *****************************************************************************/	
	unsigned char VfnUSARTRxCommunication (void)
	{
		USARTRXCommunicationSM[UsartRXCommSM.ActualState]();
		if(UsartRXCommSM.ActualState == FINISH_RXSTATE)
		{
			return 1;
		}
		else
		{
			return 0;
		}
	}
	
/*****************************************************************************
 * Function: 	VfnUSARTTxService
 * Description: Advance to Next State (Transmit next byte or finish), USARTTXCommunicationSM.
 * Parameters:	N/A
 * Caveats:		Non
 * Return:		N/A
 *****************************************************************************/	
	void VfnUSARTTxService (void)
	{
		UsartTXCommSM.ActualState = UsartTXCommSM.NextState;
	}
	
/*****************************************************************************
 * Function: 	VfnUSARTRxService
 * Description: Advance to next state (Storage byte received from USARt), USARTRXCommunicationSM.
 * Parameters:	N/A
 * Caveats:		Non
 * Return:		N/A
 *****************************************************************************/	
	void VfnUSARTRxService (void)
	{
		UsartRXCommSM.ActualState = UsartRXCommSM.NextState;
	}
	
	unsigned char VfnUSARTPackageValidation(void)
	{
		volatile unsigned short PackageCheckSum;
		unsigned char ValidationFlag=0;
		unsigned char Counter=0;
		PackageCheckSum = ((USARTRXBuffer[UART_PACKAGE_LENGTH - 2]) << 8);
		PackageCheckSum |= (USARTRXBuffer[UART_PACKAGE_LENGTH - 1]);
		ValidationFlag = VfnDataPackageValidation16(PackageCheckSum,(unsigned char*)&USARTRXBuffer[0],UART_DATA_LENGTH+UART_HEADER_LENGTH);
		if(ValidationFlag == 1)
		{
			Counter = UART_DATA_LENGTH;
			while(Counter)
			{
				USARTRXDataBuffer[(Counter)-1] = USARTRXBuffer[UART_DATA_START + (Counter)-1];
				Counter--;
			}
			return 1;
		}
		else
		{
			return 0;
		}
	}

	
/******************************************************************************
*   LOCAL Function Definitions
******************************************************************************/

	//////////////////////////////////////////////////////////////////////
	//			STATE MACHINE TO TRANSMIT DATA THROUGH USART			//
	//////////////////////////////////////////////////////////////////////
/*****************************************************************************
 * Function: 	VfnUSARTTXState0
 * Description: Load Data into the USARTTXBuffer[]
 * Parameters:	N/A
 * Caveats:		Non
 * Return:		N/A
 *****************************************************************************/	
	void VfnUSARTTXState0 (void)
	{
		unsigned char DataCounter=0;
		unsigned short CheckSum=0;
		TXFlag=0;
		USARTTXBuffer[0] = M_uCONTROLLER_ADDRESS;
		USARTTXBuffer[1] = UART_HEADER1;
		while(DataCounter != UART_DATA_LENGTH)
		{
			USARTTXBuffer[UART_DATA_START+DataCounter] = USARTTXDataBuffer[DataCounter];
			DataCounter++;
		}
		CheckSum = VfnCheckSum16((unsigned char*)&USARTTXBuffer[0],UART_DATA_LENGTH+UART_HEADER_LENGTH);
		USARTTXBuffer[UART_PACKAGE_LENGTH-3] = (unsigned char) (((CheckSum) & 0xFF00)>>8);
		USARTTXBuffer[UART_PACKAGE_LENGTH-2] = (unsigned char) (((CheckSum) & 0x00FF)); 
		USARTTXBuffer[UART_PACKAGE_LENGTH-1] = (unsigned char) (FINISH_BYTE); 
		
		UsartTXCommSM.ActualState = SEND_TXSTATE;
	}	
	
/*****************************************************************************
 * Function: 	VfnUSARTTXState1
 * Description: Transmit all data contain into the USARTTXBuffer[]
 * Parameters:	N/A
 * Caveats:		This function will transmit all data, by calling VfnUSARTTXService
				ideal for USART interrupt service.
 * Return:		N/A
 *****************************************************************************/	
	void VfnUSARTTXState1 (void)
	{
		char FIFOFlag;
		#if USART_TX_INT == ON
		#endif
		
		#if USART_RX_INT == OFF
		if(UsartTXCounter < UART_PACKAGE_LENGTH)
		{
			if(USARTTXBuffer[UsartTXCounter] != 0)
			{
				FIFOFlag = UARTCharPutNonBlocking(UART1_BASE,USARTTXBuffer[UsartTXCounter]);
				if(FIFOFlag == 1)
				{
					UsartTXCounter++;
				}
			}
			else
			{
				UsartTXCounter++;
			}	
		}	
		else
		{
			UsartTXCommSM.ActualState = FINISH_TXSTATE;
		}
		#endif
	}
	
/*****************************************************************************
 * Function: 	VfnUSARTTXState2
 * Description: Finish state, poll a Flag to know USART Package transmission
				has finished
 * Parameters:	N/A
 * Caveats:		Non
 * Return:		N/A
 *****************************************************************************/	
	void VfnUSARTTXState2 (void)
	{
		TXFlag = 1; //Package Transmission Finished
	}
	
/*****************************************************************************
 * Function: 	VfnUSARTTXState3
 * Description: Wait state.
 * Parameters:	N/A
 * Caveats:		wait to receive a Int. service from USART module
 * Return:		N/A
 *****************************************************************************/	
	void VfnUSARTTXState3 (void)
	{
		//WAIT
	}	

/*****************************************************************************
 * Function: 	void (*const USARTTXCommunicationSM[]) (void)
 * Description: USART TX Communication State Machine Definition.
 * Parameters:	N/A
 * Caveats:		
 * Return:		N/A
 *****************************************************************************/	
	void (*const USARTTXCommunicationSM[]) (void) =
	{
		VfnUSARTTXState0,
		VfnUSARTTXState1,
		VfnUSARTTXState2,
		VfnUSARTTXState3,
	};
	
	//////////////////////////////////////////////////////////////////////
	//			STATE MACHINE TO RECEIVE DATA FROM USART			//
	//////////////////////////////////////////////////////////////////////
/*****************************************************************************
 * Function: 	VfnUSARTRXState0
 * Description: Wait state. Wait for new data in RX buffer
 * Parameters:	N/A
 * Caveats:		N/A
 * Return:		N/A
 *****************************************************************************/	
	void VfnUSARTRXState0 (void)
	{
		//WAIT.
	}	
	
/*****************************************************************************
 * Function: 	VfnUSARTRXState1
 * Description: 
 * Parameters:	N/A
 * Caveats:		N/A
 * Return:		N/A
 *****************************************************************************/	
	void VfnUSARTRXState1 (void)
	{
		unsigned char UsartData;
		#if USART_RX_INT == ON
		
		#endif
		 
		#if USART_RX_INT == OFF
		if(UsartRXCounter < UART_PACKAGE_LENGTH)
		{
			if(UARTCharsAvail(UART1_BASE))
			{
				#if ADDRESS_ENABLE == ON
				UsartData = (unsigned char) UARTCharGetNonBlocking(UART1_BASE);
				if(UsartData == M_uCONTROLLER_ADDRESS)
				{
					UsartRXPackageEngage=0;
					UsartRXPackageEngageFlag=0;
				}					
				if(UsartRXPackageEngage == 1)
				{
					USARTRXBuffer[UsartRXCounter] = UsartData;
					if(UsartData == '!')
					{
						UsartRXCommSM.ActualState = FINISH_RXSTATE;
						UsartRXPackageEngage=0;
						UsartRXPackageEngageFlag=0;
					}
					UsartRXCounter++;
				}
				if(UsartRXPackageEngageFlag == 0)
				{
					if(UsartData == M_uCONTROLLER_ADDRESS)
					{
						UsartRXCounter=0;
						USARTRXBuffer[UsartRXCounter] = UsartData;
						UsartRXCounter++;
						UsartRXPackageEngage = 1;
						UsartRXPackageEngageFlag = 1;
					}
				}															
				#endif
				
				#if ADDRESS_ENABLE == OFF
				
				#endif
			}				
		}
		else
		{
			UsartRXCommSM.ActualState = FINISH_RXSTATE;
			UsartRXPackageEngage=0;
			UsartRXPackageEngageFlag=0;
		}
		#endif
		
	}	

/*****************************************************************************
 * Function: 	VfnUSARTRXState2
 * Description: 
 * Parameters:	N/A
 * Caveats:		N/A
 * Return:		N/A
 *****************************************************************************/	
	void VfnUSARTRXState2 (void)
	{
		//RXFlag = 1;
	}

/*****************************************************************************
 * Function: 	void (*const USARTRXCommunicationSM[]) (void)
 * Description: USART TX Communication State Machine Definition.
 * Parameters:	N/A
 * Caveats:		
 * Return:		N/A
 *****************************************************************************/	
	void (*const USARTRXCommunicationSM[]) (void) =
	{
		VfnUSARTRXState0,
		VfnUSARTRXState1,
		VfnUSARTRXState2,
	};	
